﻿#region File Header
//-----------------------------------------------------------------------------
// SibLib
//
// Copyright (C) 2010 Julien Villers
// This program is distributed under the terms of the 
// GNU Lesser General Public License (LGPL).
// See Docs/lgpl.txt and Docs/gpl.txt
//-----------------------------------------------------------------------------
#endregion

using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;

namespace SibLib.GameState
{
    public class NestedMenuEntry : MenuEntry
    {
        protected List<MenuEntry> m_ChildEntries;

        #region Properties
        public List<MenuEntry> ChildEntries
        {
            get { return m_ChildEntries; }
        }

        public bool IsExpanded
        {
            get;
            set;
        }

        public bool IsAlwaysExpanded
        {
            get;
            set;
        }

        public float NestedFontScale
        {
            get;
            set;
        }
        #endregion

        #region Setup
        /// <summary>
        /// Basic constructor, creates empty list of children.
        /// </summary>
        /// <param name="text"></param>
        public NestedMenuEntry(string text) :
            base(text)
        {
            m_ChildEntries = new List<MenuEntry>();
            NestedFontScale = 1.0f;
        }

        /// <summary>
        /// Helper constructor: creates a list of children of basic MenuEntry type.
        /// </summary>
        /// <param name="text">Root entry text</param>
        /// <param name="children">List of child entries texts</param>
        public NestedMenuEntry(string text, params string[] children) :
            base(text)
        {
            m_ChildEntries = new List<MenuEntry>(children.Length);
            for (int i = 0; i != children.Length; i++)
                m_ChildEntries.Add(new MenuEntry(children[i]));
            NestedFontScale = 1.0f;
        }
        #endregion

        #region Update

        protected internal override void OnSelectEntry(PlayerIndex playerIndex)
        {
            base.OnSelectEntry(playerIndex);

            if (!IsAlwaysExpanded)
                IsExpanded = !IsExpanded;
        }

        public override void Update(MenuScreen screen, bool isSelected, GameTime gameTime)
        {
            base.Update(screen, isSelected && !IsExpanded, gameTime);

            if (!(screen is NestedMenuScreen))
                throw new InvalidOperationException("NestedMenuEntry found in non nested MenuScreen");

            // Update each nested MenuEntry object.
            int selectedSub = ((NestedMenuScreen)screen).SelectedNestedEntry;
            for (int i = 0; i != m_ChildEntries.Count; i++)
            {
                MenuEntry entry = m_ChildEntries[i];
                entry.Update(screen, (selectedSub == i), gameTime);
            }
        }

        #endregion

        #region Draw

        private const float SPACING_FACTOR = 0.8f;

        public override void Draw(MenuScreen screen, Vector2 position, bool isSelected, GameTime gameTime, float fontScale)
        {
            base.Draw(screen, position, isSelected && !IsExpanded, gameTime, fontScale);

            if (IsExpanded || IsAlwaysExpanded)
            {
                position.X += 64;
                position.Y += (base.GetHeight(screen) * SPACING_FACTOR);
                int selectedSub = ((NestedMenuScreen)screen).SelectedNestedEntry;

                for (int i = 0; i != m_ChildEntries.Count; i++)
                {
                    MenuEntry entry = m_ChildEntries[i];
                    entry.Draw(screen, position, (selectedSub == i), gameTime, NestedFontScale);
                    position.Y += (entry.GetHeight(screen) * SPACING_FACTOR * NestedFontScale);
                }
            }
        }

        public override int GetHeight(MenuScreen screen)
        {
            int height = base.GetHeight(screen);
            if (IsExpanded || IsAlwaysExpanded)
            {
                foreach (MenuEntry entry in m_ChildEntries)
                    height += (int)(entry.GetHeight(screen) * SPACING_FACTOR * NestedFontScale);
            }
            return height;
        }

        #endregion
    }
}
